#include "xtools.h"
#include <sstream>
extern "C" {
#include <libavcodec/avcodec.h>
}
#include <chrono>
using namespace std;

void MSleep(unsigned int ms) {
  auto beg = clock();
  for (int i = 0; i < ms; i++) {
    this_thread::sleep_for(1ms);
    if ((clock() - beg) / (CLOCKS_PER_SEC / 1000) >= ms)
      break;
  }
}
long long NowMs() { return clock() / (CLOCKS_PER_SEC / 1000); }
void XFreeFrame(AVFrame **frame) {
  if (!frame || !(*frame))
    return;
  av_frame_free(frame);
  *frame = nullptr;
}

void XThread::Start() {
  unique_lock<mutex> lock(m_);
  static int i = 0;
  index_ = ++i;
  // 设置为未退
  is_exit_ = false;
  // 启动线程
  th_ = thread(&XThread::Main, this);
  stringstream s;
  s << "XThread::Start" << index_;
  LOGINFO(s.str());
  // // 分离主线程与子线程 这里不做，因该由Stop控制
  // th_.detach();
}

void XThread::Stop() {
  stringstream s;
  s << "XThread::Stop() begin" << index_;
  LOGINFO(s.str());
  is_exit_ = true;
  if (th_.joinable()) { // 判断线程是否可以等待，保真不会出错
    th_.join();
  }
  s.str("");
  s << "XThread::Stop() end" << index_;
  LOGINFO(s.str());
}


XPara *XPara::Create() { return new XPara(); }

XPara::~XPara() {
  if (para)
    avcodec_parameters_free(&para);
  if (time_base) {
    delete time_base;
    time_base = nullptr;
  }
}
XPara::XPara() {
  para = avcodec_parameters_alloc();
  time_base = new AVRational();
}

AVPacket *XAVPacketList::Pop() {
  unique_lock<mutex> lock(m_);
  if (pkts_.empty())
    return nullptr;
  auto p = pkts_.front();
  pkts_.pop_front();
  return p;
}

void XAVPacketList::Push(AVPacket *pkt) {
  unique_lock<mutex> lock(m_);
  auto p = av_packet_alloc();
  av_packet_ref(p, pkt); // 引用计算 减少数据复制，线程安全
  pkts_.push_back(p);
  // 超出最大空间，清理数据到关键帧数据
  if (pkts_.size() > max_packets_) {
    if (pkts_.front()->flags & AV_PKT_FLAG_KEY) {
      av_packet_free(&pkts_.front()); // 清理关键帧
      pkts_.pop_front();
      return;
    }
    while (!pkts_.empty()) {
      if (pkts_.front()->flags & AV_PKT_FLAG_KEY) {
        return;
      }
      av_packet_free(&pkts_.front());
      pkts_.pop_front();
    }
  }
}
